package com.sh.service.permission.impl;

import com.sh.common.context.AppContextHolder;
import com.sh.config.Configure;
import com.sh.config.OssClientConfig;
import com.sh.dao.IUserPermissionDao;
import com.sh.entity.UserPermission;
import com.sh.enums.OssTypeEnum;
import com.sh.enums.StatusEnum;
import com.sh.pojo.bo.UpdatePermissionBO;
import com.sh.pojo.dto.PermissionCacheDTO;
import com.sh.pojo.dto.ResourcePathLevelDTO;
import com.sh.pojo.dto.ResourceTreeDTO;
import com.sh.service.cache.RedisService;
import com.sh.service.permission.IUserPermissionService;
import com.sh.service.store.IOSService;
import com.sh.utils.CommonUtils;
import com.sh.utils.IdGeneratorUtil;
import com.sh.utils.PathUtil;
import com.sh.utils.RedisKeyUtil;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 用户权限
 * */
@Service
@Slf4j
public class UserPermissionService implements IUserPermissionService {
    @Autowired
    private IUserPermissionDao userPermissionDao;
    @Autowired
    private OssClientConfig ossClientConfig;
    @Autowired
    private RedisService redisService;
//    @Autowired
//    private CachePermissionService cachePermissionService;
    @Autowired
    private IOSService osService;
    @Autowired
    private IdGeneratorUtil idGeneratorUtil;


    @PostConstruct
    public void initPermissionCache() {
        // 初始化权限信息
        log.info("Initializing Permission Cache...");
        List<UserPermission> permissionList = getAllUserPermission();
        redisService.multiSetPermission(permissionList);

//        permissionList.forEach(p -> {
//            String userId = p.getUserId();
//            String bucket = p.getBucket();
//            String path = p.getPath();
//            PermissionCacheDTO cacheDTO = PermissionCacheDTO.builder().id(p.getId()).permission(p.getPermission()).build();
////            cachePermissionService.updateData(OssClientConfig.resourceType, userId, bucket, path, cacheDTO);
//        });
    }

    @Override
    public List<UserPermission> getAllUserPermission() {
        Integer storeTypeCode = OssTypeEnum.getCode(ossClientConfig.getResourceType());
        UserPermission example = UserPermission.builder().storeType(storeTypeCode).status(StatusEnum.ENABLE.getCode()).build();
        return userPermissionDao.findAll(Example.of(example));
    }

    @Override
    @Transactional
    public void setUserPermission(UpdatePermissionBO bo) {
        String createBy=AppContextHolder.getUserId();
        String userId = bo.getUserId();
        String bucket = bo.getBucket();
        String path = PathUtil.getPathNotEndWithSeparator(bo.getPath());
        Integer permission = Integer.valueOf(bo.getPermission());
        Integer storeTypeCode=OssTypeEnum.getCode(ossClientConfig.getResourceType());
        // 遍历children path
        List<ResourceTreeDTO> children = osService.listDirectories(bucket,path,0,Configure.sysManageFolderLevel);
        List<ResourcePathLevelDTO> paths = CommonUtils.collectPaths(children);
        List<UserPermission> updateList = new ArrayList<>();
        for (ResourcePathLevelDTO c : paths) {
            UserPermission userPermission = UserPermission.builder().id(idGeneratorUtil.generateId()).userId(userId).bucket(bucket).path(c.getPath()).permission(permission).level(c.getLevel()).storeType(storeTypeCode).build();
            userPermission.setCreateBy(createBy);
            userPermission.setCreateDate(new Date());
            updateList.add(userPermission);
        }
        List<UserPermission> userPermissionList= userPermissionDao.saveAll(updateList);
        if (userPermissionList == null || userPermissionList.isEmpty()) {
            return ;
        }
        redisService.multiSetPermission(userPermissionList);
    }

    @Override
    public List<String> listBucketByUser(String userId) {
        return userPermissionDao.listDistinctBucketByUserId(userId,StatusEnum.ENABLE.getCode());
    }

    @Override
    public PermissionCacheDTO getUserPermissionByPath(String userId, String bucket, String path) {
      return   redisService.getPermissionByPath(ossClientConfig.getResourceType(),userId,bucket,path);
    }

    @Override
    public List<String> getUserMaxPermission(String bucket) {
        String userId = AppContextHolder.getUserId();
        Boolean isAdmin = AppContextHolder.getAdmin();
        if (isAdmin) {
            List<String> permissionList = new ArrayList<>();
            List<ResourceTreeDTO> list = osService.listDirectories(bucket, null, 1, 2);
            if (list == null || list.isEmpty()) {
                return permissionList;
            }
            list.forEach(l -> {
                permissionList.add(l.getPath());
            });
            return permissionList;
        }
        return userPermissionDao.findMaxLevelPermission(userId, bucket, StatusEnum.ENABLE.getCode());
    }

    @Override
    public List<ResourceTreeDTO> getUserPermissionByBucket(String userId, String bucket,String path) {
        // 查询所有目录
        List<ResourceTreeDTO> allList = osService.listDirectories(bucket, path, 0, Configure.sysManageFolderLevel);
        // 查询缓存权限
        Map<String, PermissionCacheDTO> userPermissionList= redisService.getUserPermissions(ossClientConfig.getResourceType(),userId,bucket,path);
        if(userPermissionList==null||userPermissionList.isEmpty()){
            return allList;
        }

        assignPermissions(allList,userPermissionList,userId,bucket);

        //

//        Map<String, PermissionCacheDTO> map = redisService.getUserPermissions(OssClientConfig.resourceType, userId, bucket);
//        if (map == null || map.isEmpty()) {
//            return null;
//        }
//        List<PermissionCacheDTO> list = new ArrayList<>();
//        for (PermissionCacheDTO p : map.values()) {
//            list.add(p);
//        }
//        return list;

      return allList;
    }

    // 递归地将权限信息赋值到目录树中
   private void assignPermissions(List<ResourceTreeDTO> resourceTree, Map<String, PermissionCacheDTO> userPermissionList,String userId,String bucket) {
        for (ResourceTreeDTO node : resourceTree) {
            // 获取当前节点的路径
            String path = node.getPath();

            // 在 userPermissionList 中查找该路径对应的权限信息
            String permissionKey = RedisKeyUtil.getPermissionKey(ossClientConfig.getResourceType(), userId, bucket, node.getPath());
            PermissionCacheDTO permissionCache = userPermissionList.get(permissionKey);
            if (permissionCache != null) {
                // 将权限赋值到当前节点
                node.setPermission(permissionCache.getPermission());
            }

            // 递归处理子节点（children）
            if (node.getChildren() != null && !node.getChildren().isEmpty()) {
                assignPermissions(node.getChildren(), userPermissionList,userId,bucket);
            }
        }
    }


}
